const { Dormitory, Student } = require('../models/db');

const ok = (res, data, extra = {}) => res.json({ success: true, data, ...extra });
const fail = (res, code = 500, message = '服务器错误') => res.status(code).json({ success: false, message, code });

const mapDormitoryToClient = (d) => {
  // 确保students是数组
  const students = (d.students && Array.isArray(d.students)) ? d.students : [];
  const currentCount = students.length;
  const capacity = d.capacity || 8;
  const occupancyRate = capacity > 0 ? Math.round((currentCount / capacity) * 100) : 0;
  
  // 根据入住情况判断状态
  let status = '空置';
  if (currentCount === 0) {
    status = '空置';
  } else if (currentCount < capacity) {
    status = '部分入住';
  } else if (currentCount === capacity) {
    status = '已满';
  }
  
  // 根据学生性别判断类型
  let type = '8人间'; // 默认值
  if (students.length > 0) {
    const genders = new Set(students.map(s => s.gender || s.sex).filter(Boolean));
    if (genders.size === 1) {
      type = Array.from(genders)[0] === '男' ? '男生宿舍' : '女生宿舍';
    } else if (genders.size > 1) {
      type = '混合宿舍';
    } else {
      type = '8人间';
    }
  } else {
    // 根据宿舍楼名称判断（临时方案）
    if (d.building && (d.building.includes('11') || d.building.includes('12') || d.building.includes('13'))) {
      type = '标准宿舍';
    } else {
      type = '8人间';
    }
  }
  
  return {
    id: d._id?.toString(),
    building: d.building,
    floor: d.floor,
    roomNumber: d.roomNumber,
    capacity: capacity,
    type: type,
    gender: students.length > 0 ? (students[0].gender === '男' ? 'male' : 'female') : undefined,
    currentCount: currentCount,
    occupancyRate: occupancyRate,
    status: status,
    comment: d.comment || '',
    students: students.map(s => ({
      id: s._id?.toString(),
      studentId: s.studentId || s.id,
      name: s.name,
      gender: s.gender
    })),
    createdAt: d.createdAt ? new Date(d.createdAt).toISOString() : undefined,
    updatedAt: d.updatedAt ? new Date(d.updatedAt).toISOString() : undefined,
  };
};

const mapClientToDormitory = (body) => ({
  building: body.building,
  floor: body.floor,
  roomNumber: body.roomNumber,
  capacity: body.capacity || 8,
  comment: body.comment,
  updatedAt: new Date(),
});

exports.getAllDormitories = async (req, res) => {
  try {
    const { page = 1, limit = 20, building, floor } = req.query;
    const skip = (parseInt(page) - 1) * parseInt(limit);
    const query = {};
    
    if (building) query.building = building;
    if (floor) query.floor = parseInt(floor);
    
    const dormitories = await Dormitory.find(query)
      .populate({
        path: 'students',
        select: 'studentId name gender phone academy class status',
        populate: {
          path: 'class',
          select: 'className'
        }
      })
      .sort({ building: 1, floor: 1, roomNumber: 1 })
      .skip(skip)
      .limit(parseInt(limit));
    
    const total = await Dormitory.countDocuments(query);
    ok(res, dormitories.map(mapDormitoryToClient), {
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        totalPages: Math.ceil(total / parseInt(limit))
      }
    });
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.getDormitoryById = async (req, res) => {
  try {
    const d = await Dormitory.findById(req.params.id)
      .populate({
        path: 'students',
        select: 'studentId name gender phone academy class status',
        populate: {
          path: 'class',
          select: 'className'
        }
      });
    if (!d) return fail(res, 404, '未找到该宿舍');
    ok(res, mapDormitoryToClient(d));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.createDormitory = async (req, res) => {
  try {
    const payload = mapClientToDormitory(req.body || {});
    if (!payload.building || !payload.floor || !payload.roomNumber) {
      return fail(res, 400, '缺少必要字段: building | floor | roomNumber');
    }
    
    const exist = await Dormitory.findOne({
      building: payload.building,
      floor: payload.floor,
      roomNumber: payload.roomNumber
    });
    if (exist) return fail(res, 400, '该宿舍已存在');
    
    const created = await Dormitory.create({ ...payload, students: [] });
    ok(res, mapDormitoryToClient(created));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.updateDormitory = async (req, res) => {
  try {
    const payload = mapClientToDormitory(req.body || {});
    payload.updatedAt = new Date();
    const updated = await Dormitory.findByIdAndUpdate(req.params.id, payload, { new: true })
      .populate('students', 'studentId name');
    if (!updated) return fail(res, 404, '未找到该宿舍');
    ok(res, mapDormitoryToClient(updated));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

exports.deleteDormitory = async (req, res) => {
  try {
    const deleted = await Dormitory.findByIdAndDelete(req.params.id);
    if (!deleted) return fail(res, 404, '未找到该宿舍');
    ok(res, { id: req.params.id });
  } catch (e) {
    fail(res, 500, e.message);
  }
};

// 添加学生到宿舍
exports.addStudentToDormitory = async (req, res) => {
  try {
    const { studentId } = req.body;
    if (!studentId) return fail(res, 400, '缺少必要字段: studentId');
    
    const dormitory = await Dormitory.findById(req.params.id);
    if (!dormitory) return fail(res, 404, '未找到该宿舍');
    
    if (dormitory.students.length >= dormitory.capacity) {
      return fail(res, 400, '宿舍已满');
    }
    
    const student = await Student.findById(studentId);
    if (!student) return fail(res, 404, '未找到该学生');
    
    if (dormitory.students.includes(studentId)) {
      return fail(res, 400, '学生已在该宿舍');
    }
    
    dormitory.students.push(studentId);
    dormitory.updatedAt = new Date();
    await dormitory.save();
    
    // 更新学生的宿舍信息
    student.dormitory = dormitory._id;
    await student.save();
    
    const updated = await Dormitory.findById(req.params.id)
      .populate('students', 'studentId name gender');
    ok(res, mapDormitoryToClient(updated));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

// 从宿舍移除学生
exports.removeStudentFromDormitory = async (req, res) => {
  try {
    const { studentId } = req.body;
    if (!studentId) return fail(res, 400, '缺少必要字段: studentId');
    
    const dormitory = await Dormitory.findById(req.params.id);
    if (!dormitory) return fail(res, 404, '未找到该宿舍');
    
    dormitory.students = dormitory.students.filter(id => id.toString() !== studentId);
    dormitory.updatedAt = new Date();
    await dormitory.save();
    
    // 更新学生的宿舍信息
    const student = await Student.findById(studentId);
    if (student && student.dormitory?.toString() === req.params.id) {
      student.dormitory = null;
      await student.save();
    }
    
    const updated = await Dormitory.findById(req.params.id)
      .populate('students', 'studentId name gender');
    ok(res, mapDormitoryToClient(updated));
  } catch (e) {
    fail(res, 500, e.message);
  }
};

